본문으로 건너뛰기

RBI Proxy 소개

SOFTCAMP SHIELDGate 격리 브라우저 연동을 위한 HTTP/HTTPS 프록시 서비스


📋 목차

  1. 개요
  2. RBIProxy란?
  3. 전체 아키텍처
  4. 주요 구성 요소
  5. 동작 원리
  6. PAC 파일 설정
  7. 보안 메커니즘
  8. REST API
  9. 기술 스택
  10. 사용 사례

개요

RBIProxy는 사용자의 일반 브라우저 트래픽을 SOFTCAMP SHIELDGate 격리 브라우저로 자동 연결하는 중간 프록시 서버입니다.

사용자는 평소처럼 웹 브라우징을 하지만, 모든 웹 접속이 격리된 환경(RBI)에서 실행되어 보안 위협으로부터 안전하게 보호됩니다.

핵심 가치

  • 투명한 보안: 사용자 경험을 해치지 않으면서 보안 강화 (자동 리다이렉트)
  • 중앙 집중식 제어: 단일 프록시로 모든 웹 트래픽을 중앙에서 통제
  • 간단한 중계 구조: URL 변환 및 SHIELDGate 연동만 수행 (복잡한 정책은 SHIELDGate에서 처리)

RBIProxy란?

RBI (Remote Browser Isolation)

원격 브라우저 격리 기술은 사용자의 웹 브라우징을 물리적으로 격리된 원격 환경에서 실행하는 보안 솔루션입니다.

전통적인 웹 접속:
[사용자 PC] ──→ [인터넷 웹사이트]

악성코드 다운로드 위험
제로데이 공격 노출
피싱 사이트 직접 접속

RBI 적용 후:
[사용자 PC] ──→ [격리된 브라우저] ──→ [인터넷 웹사이트]

악성코드가 격리 환경에서만 실행
사용자 PC는 안전

RBIProxy의 역할

RBIProxy는 PAC 필터링을 통과한 트래픽을 SHIELDGate로 변환하는 중계기입니다:

🎯 필터링 구조

┌──────────────────────────────────────────────────────────────┐
│ PAC 파일 (사용자 PC에서 실행) │
│ "어느 사이트는 프록시 거치고, 어느 건 직접?" │
└────────────┬─────────────────────────────┬───────────────────┘
↓ ↓
[허용 사이트] [차단 사이트]
naver.com example.com
microsoft.com unknown-site.com
내부 IP (192.168.x.x) 기타 모든 사이트
↓ ↓
DIRECT (프록시 안 거침) PROXY 10.14.10.176:9999
↓ ↓
[직접 접속] ┌─────────────────────────────┐
│ RBIProxy 서버 │
│ "URL 변환기" │
└──────┬──────────────────────┘

URL 변환 수행

https://shieldgate.softcamp.co.kr/
gate-proxy?currentTab=true&url=원본URL

HTML 리다이렉트 응답

┌───────────────────────┐
│ 사용자 브라우저가 │
│ 자동으로 이동 │
└──────┬────────────────┘

┌─────────────────┐
│ SHIELDGate │
│ gate-proxy │
└──────┬──────────┘

┌─────────────────┐
│ rb-app │
│ (격리 브라우저) │
└──────┬──────────┘

[실제 웹사이트 접속]

구체적인 예시

예시 1: naver.com 접속 (허용 사이트)

[사용자] naver.com 입력

[PAC 파일] "naver.com? 어? 너 허용이구나!"

[결정] "그럼 너는 DIRECT"

[결과] naver.com에 바로 접속 ✅ (RBIProxy 안 거침)

예시 2: example.com 접속 (차단 대상 사이트)

[사용자] example.com 입력

[PAC 파일] "example.com? 허용 목록에 없네"

[결정] "너는 RBIProxy로 보내"

[RBIProxy] URL 변환
원본: http://example.com

변환: https://shieldgate.softcamp.co.kr/gate-proxy?currentTab=true&url=http://example.com

[HTML 리다이렉트 응답]
<meta http-equiv="refresh" content="0;url=변환된URL"/>

[사용자 브라우저] 자동으로 SHIELDGate URL로 이동

[SHIELDGate] gate-proxy가 rb-app(격리 브라우저) 실행

[rb-app] 격리된 환경에서 example.com 접속

[결과] 사용자는 격리 브라우저로 example.com 이용 ✅

전체 아키텍처

단순화된 흐름도

┌─────────────────────┐
│ 사용자 PC │
│ (일반 브라우저) │
│ Chrome / Edge 등 │
└──────────┬──────────┘

│ ① Windows 프록시 설정 (PAC)
│ - 허용 사이트 → DIRECT
│ - 차단 사이트 → PROXY 10.14.10.176:9999

┌─────────────────────┐
│ RBIProxy 서버 │
│ (이 프로젝트) │
│ - URL 변환만 │
└──────────┬──────────┘

│ ② HTML 리다이렉트
│ shieldgate.softcamp.co.kr/
│ gate-proxy?currentTab=true&url=원본URL

┌─────────────────────┐
│ SHIELDGate │
│ (격리 브라우저) │
│ - gate-proxy │
└──────────┬──────────┘

│ ③ rb-app 실행

┌─────────────────────┐
│ rb-app │
│ (격리 브라우저) │
└──────────┬──────────┘

│ ④ 실제 웹사이트 접속

┌─────────────────────┐
│ 인터넷 웹사이트 │
│ example.com 등 │
└─────────────────────┘

┌─────────────────────┐
│ 인터넷 웹사이트 │
│ example.com 등 │
└─────────────────────┘

### 상세 데이터 흐름

**중요**: PAC 파일이 1차 필터링을 수행합니다!

┌─────────────────────────────────────────────────────────────────┐
│ 사용자 PC │
│ │
│ [Chrome/Edge] 사용자가 URL 입력 │
│ ↓ │
│ ┌─────────────────────────────────────────────┐ │
│ │ PAC 파일 (필터링) │ │
│ │ "이 사이트 어디로 보낼까?" │ │
│ └──────────┬──────────────────────────────────┘ │
│ │ │
│ ┌──────┴───────┐ │
│ ↓ ↓ │
│ [허용 사이트] [차단 대상] │
│ naver.com example.com │
│ ↓ ↓ │
│ DIRECT PROXY 10.14.10.176:9999 │
│ │
└──────┼──────────────┼──────────────────────────────────────────┘
│ │
↓ │ RBIProxy로 전달
[naver.com] ↓
직접 접속 ┌─────────────────────────────────────────────────────────────────┐
│ RBIProxy 서버 │
│ (URL 변환기) │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 1. 요청 수신 (9999 포트) │ │
│ └──────────────────┬───────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────▼───────────────────────────────────────┐ │
│ │ 2. URL 변환 │ │
│ │ 원본: http://example.com │ │
│ │ → │ │
│ │ 변환: https://shieldgate.softcamp.co.kr/ │ │
│ │ gate-proxy?currentTab=true&url=http://example.com│
│ └──────────────────┬───────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────▼───────────────────────────────────────┐ │
│ │ 3. HTML 리다이렉트 응답 │ │
│ │ │ │
│ └──────────────────┬───────────────────────────────────────┘ │
│ │ │
└─────────────────────┼────────────────────────────────────────────┘


┌─────────────────────────────┐
│ 사용자 브라우저가 │
│ 자동으로 SHIELDGate로 이동 │
└─────────────┬───────────────┘

┌─────────────────────┐
│ SHIELDGate │
│ gate-proxy │
└──────────┬──────────┘

│ rb-app 실행

┌─────────────────────┐
│ rb-app │
│ (격리 브라우저) │
└──────────┬──────────┘

│ 직접 인터넷 접속

┌─────────────────────┐
│ 인터넷 웹사이트 │
│ example.com │
└─────────────────────┘

***

## 주요 구성 요소

### 1. Windows PAC (Proxy Auto-Config)

**위치**: 사용자 PC의 Windows 프록시 설정

**역할**: **1차 필터링 - 사이트별로 프록시 사용 여부 결정**

**중요**: PAC 파일이 먼저 판단합니다!
- ✅ **허용 사이트** (naver.com, microsoft.com 등) → `DIRECT` (프록시 안 거침)
- ⚠️ **일반 사이트** (example.com 등) → `PROXY 10.14.10.176:9999` (RBIProxy로)

**예시 PAC 파일** (`pac.js`):

```javascript
function FindProxyForURL(url, host) \{
// 1. SHIELDGate 자체는 DIRECT (무한 루프 방지)
if (dnsDomainIs(host, "shieldgate.softcamp.co.kr") ||
dnsDomainIs(host, "security365.co.kr")) \{
return "DIRECT";
\}

// 2. 허용 사이트 목록 (예외 처리)
if (dnsDomainIs(host, "naver.com") ||
dnsDomainIs(host, "microsoft.com") ||
dnsDomainIs(host, "office365.com")) \{
return "DIRECT"; // ← naver.com? 어? 너 허용이구나! DIRECT!
\}

// 3. 내부 네트워크는 DIRECT
if (isPlainHostName(host) ||
shExpMatch(host, "*.local") ||
isInNet(dnsResolve(host), "10.0.0.0", "255.0.0.0") ||
isInNet(dnsResolve(host), "172.16.0.0", "255.240.0.0") ||
isInNet(dnsResolve(host), "192.168.0.0", "255.255.0.0") ||
isInNet(dnsResolve(host), "127.0.0.0", "255.255.255.0")) \{
return "DIRECT";
\}

// 4. 기본 규칙: RBIProxy로 보냄
return "PROXY 10.14.10.176:9999"; // ← example.com? 너는 RBIProxy로!
\}

실제 동작:

사용자가 naver.com 입력

PAC: "naver.com? 어? 너 허용이구나!"

PAC: "그럼 너는 DIRECT"

naver.com에 바로 접속 ✅ (RBIProxy 거치지 않음)


사용자가 example.com 입력

PAC: "example.com? 허용 목록에 없네"

PAC: "너는 RBIProxy로 보내" (PROXY 10.14.10.176:9999)

RBIProxy로 전달 → 다음 단계 진행

PAC 파일 적용 방법:

  1. 수동 적용 (개별 PC):

    • Windows 설정 → 네트워크 및 인터넷 → 프록시
    • "자동 프록시 설정 사용" 활성화
    • 스크립트 주소: http://10.14.10.176:9999/RestAPI/pac.js
  2. GPO 적용 (도메인 일괄 적용):

    그룹 정책 편집기
    → 사용자 구성 → 기본 설정 → Windows 설정 → 레지스트리
    → HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings
    → AutoConfigURL = "http://10.14.10.176:9999/RestAPI/pac.js"
  3. PAC 파일 다운로드:

    # RBIProxy가 제공하는 PAC 파일
    curl http://10.14.10.176:9999/RestAPI/pac.js -o pac.js

2. RBIProxy 서버

언어: Go (Golang)
포트:

  • 9999: 프록시 서버 (메인 기능)
  • 80: REST API 서버 (관리/모니터링)

배포: Kubernetes (Docker 컨테이너)

주요 역할: "URL 변환기"

PAC에서 보낸 모든 트래픽을 받아서 SHIELDGate URL 형식으로 변환합니다.

┌─────────────────────────────────────────────────────┐
│ RBIProxy 서버 (URL 변환기) │
│ │
│ ① 프록시 요청 수신 (9999 포트) │
│ ↓ │
│ ② URL 변환 │
│ 원본: http://example.com │
│ → │
│ 변환: https://shieldgate.softcamp.co.kr/ │
│ gate-proxy?currentTab=true&url=원본URL │
│ ↓ │
│ ③ HTML 리다이렉트 응답 │
│ <meta http-equiv="refresh" │
│ content="0;url=변환URL"/> │
│ │
└─────────────────────────────────────────────────────┘

핵심 코드 (src/main.go 317~320번 줄):

func redirectUrl(url string) string \{
// SHIELDGate 방식: URL을 쿼리 파라미터로 전달
return cfg.RBIProxy.RBI.BaseURL +
"gate-proxy?currentTab=true&url=" + url
\}

실제 변환 예시:

입력: http://example.com

출력: https://shieldgate.softcamp.co.kr/gate-proxy?currentTab=true&url=http://example.com

3. SHIELDGate (격리 브라우저)

URL: https://shieldgate.softcamp.co.kr

구성:

  • gate-proxy: 웹 인터페이스 (URL을 받아서 rb-app 실행)
  • rb-app: 격리 브라우저 엔진 (실제 웹사이트 접속 및 렌더링)

역할:

  • gate-proxy가 URL 파라미터를 받아서 rb-app(격리 브라우저) 실행
  • rb-app이 격리된 환경에서 실제 웹사이트 렌더링
  • 사용자에게 화면만 스트리밍
  • 보안 정책 적용 (다운로드/업로드/복사 제어 등)

URL 규약:

https://shieldgate.softcamp.co.kr/gate-proxy?currentTab=true&url=<원본URL>

동작 방식:

gate-proxy URL로 들어옴

gate-proxy가 url 파라미터 추출

rb-app(격리 브라우저) 실행

rb-app이 실제 웹사이트에 직접 접속

사용자에게 화면 스트리밍

예시:

변환된 URL: https://shieldgate.softcamp.co.kr/gate-proxy?currentTab=true&url=http://example.com
→ gate-proxy가 rb-app 실행
→ rb-app이 http://example.com 접속

동작 원리

🌟 전체 시나리오: 2가지 경로

사용자가 웹사이트에 접속할 때 PAC 파일이 먼저 판단합니다:

사용자가 URL 입력

┌───────────────────────────────┐
│ PAC 파일 (1차 필터) │
│ "이 사이트 어디로 보낼까?" │
└───────┬───────────────────────┘

┌────┴─────┐
↓ ↓
[허용] [차단]
↓ ↓
DIRECT PROXY
↓ ↓
[끝] [RBIProxy]

[SHIELDGate]

시나리오 A: 허용 사이트 (naver.com)

PAC에서 끝나는 케이스 - RBIProxy 거치지 않음

Step-by-Step 흐름

[Step 1] 사용자가 Chrome에 "naver.com" 입력


[Step 2] PAC 파일 실행 (사용자 PC에서)
function FindProxyForURL(url, "naver.com") \{
if (dnsDomainIs(host, "naver.com")) \{
return "DIRECT"; // ← 여기서 결정!
\}
\}


[Step 3] PAC 판단: "naver.com? 어? 너 허용이구나!"


[Step 4] 결정: "그럼 너는 DIRECT" (프록시 사용 안함)


[Step 5] naver.com에 직접 접속 ✅

결과: RBIProxy, SHIELDGate 모두 거치지 않음

시나리오 B: 차단 사이트 (example.com)

RBIProxy + SHIELDGate를 거치는 케이스

Step-by-Step 흐름

[Step 1] 사용자가 Chrome에 "example.com" 입력


[Step 2] PAC 파일 실행 (사용자 PC에서)
function FindProxyForURL(url, "example.com") \{
// 허용 목록에 없음
return "PROXY 10.14.10.176:9999"; // ← 여기서 결정!
\}


[Step 3] PAC 판단: "example.com? 허용 목록에 없네"


[Step 4] 결정: "너는 RBIProxy로 보내"


[Step 5] RBIProxy 수신
→ 프록시 요청 수신 (9999 포트)


[Step 6] URL 변환 수행
→ 원본: http://example.com
→ 변환: https://shieldgate.softcamp.co.kr/gate-proxy?currentTab=true&url=http://example.com


[Step 7] HTML 리다이렉트 응답 생성
→ <meta http-equiv="refresh" content="0;url=변환URL"/>
→ HTTP 202 Accepted 응답


[Step 8] 사용자 브라우저가 자동으로 SHIELDGate URL로 이동


[Step 9] SHIELDGate gate-proxy가 URL 파라미터 확인
→ url=http://example.com 추출


[Step 10] gate-proxy가 rb-app(격리 브라우저) 실행


[Step 11] rb-app이 격리된 환경에서 example.com 직접 접속


[Step 12] 웹사이트 렌더링 후 사용자에게 화면 스트리밍


[완료] 사용자는 격리 브라우저로 example.com을 안전하게 이용 ✅

시나리오 비교

단계naver.com (허용)example.com (차단)
PAC 필터DIRECT → 직접 접속PROXY → RBIProxy로
RBIProxy거치지 않음URL 변환 → SHIELDGate로
최종 접속naver.com 직접rb-app(격리 브라우저) 경유
보안 수준일반격리 환경
단계 수5단계12단계

PAC 파일 설정

PAC 파일이란?

**PAC (Proxy Auto-Config)**는 JavaScript로 작성된 파일로, 브라우저가 어떤 프록시를 사용할지 동적으로 결정합니다.

RBIProxy용 PAC 파일 작성

RBIProxy는 /RestAPI/pac.js 엔드포인트를 통해 PAC 파일을 제공합니다.

기본 PAC 파일 구조

function FindProxyForURL(url, host) \{
// 1. SHIELDGate 자체는 프록시 우회 (무한 루프 방지)
if (dnsDomainIs(host, "shieldgate.softcamp.co.kr") ||
dnsDomainIs(host, "security365.co.kr") ||
dnsDomainIs(host, "softcamp.co.kr")) \{
return "DIRECT";
\}

// 2. 내부 네트워크 (사설 IP) 우회
if (isPlainHostName(host) ||
shExpMatch(host, "*.local") ||
isInNet(dnsResolve(host), "10.0.0.0", "255.0.0.0") ||
isInNet(dnsResolve(host), "172.16.0.0", "255.240.0.0") ||
isInNet(dnsResolve(host), "192.168.0.0", "255.255.0.0") ||
isInNet(dnsResolve(host), "127.0.0.0", "255.255.255.0")) \{
return "DIRECT";
\}

// 3. 특정 도메인 예외 처리
if (dnsDomainIs(host, "microsoft.com") ||
dnsDomainIs(host, "azure.com") ||
dnsDomainIs(host, "office365.com")) \{
return "DIRECT"; // Microsoft 서비스는 프록시 우회
\}

// 4. 기본 규칙: RBIProxy를 통해 프록시
return "PROXY 10.14.10.176:9999";
\}

PAC 파일 주요 함수

함수설명예시
dnsDomainIs(host, domain)도메인 일치 확인dnsDomainIs(host, "example.com")
shExpMatch(host, pattern)와일드카드 패턴 매칭shExpMatch(host, "*.google.com")
isInNet(host, network, mask)IP 네트워크 범위 확인isInNet(dnsResolve(host), "192.168.0.0", "255.255.0.0")
isPlainHostName(host)호스트명만 있는지 확인 (도메인 없음)isPlainHostName("localhost")

PAC 파일 배포 방법

방법 1: RBIProxy에서 직접 배포

RBIProxy는 /RestAPI/pac.js 엔드포인트를 통해 PAC 파일을 제공합니다.

# PAC 파일 접근
http://10.14.10.176:9999/RestAPI/pac.js

Windows 프록시 설정:

  1. 설정 → 네트워크 및 인터넷 → 프록시
  2. "설정 자동 검색" OFF
  3. "설정 스크립트 사용" ON
  4. 스크립트 주소: http://10.14.10.176:9999/RestAPI/pac.js

방법 2: 웹 서버에서 배포

별도 웹 서버(Apache, Nginx 등)에 PAC 파일을 배포할 수도 있습니다.

# Nginx 설정 예시
location /proxy.pac \{
alias /var/www/html/pac.js;
types \{
application/x-ns-proxy-autoconfig pac;
\}
\}

방법 3: GPO (Group Policy Object) 배포

Active Directory 환경에서 일괄 적용:

  1. 그룹 정책 관리 콘솔 열기

  2. 새 GPO 생성: "RBIProxy PAC 설정"

  3. 편집 → 사용자 구성 → 기본 설정 → Windows 설정 → 레지스트리

  4. 새 레지스트리 항목:

    Hive: HKEY_CURRENT_USER
    키 경로: Software\Microsoft\Windows\CurrentVersion\Internet Settings
    값 이름: AutoConfigURL
    값 형식: REG_SZ
    값 데이터: http://10.14.10.176:9999/RestAPI/pac.js

PAC 파일 예외 처리 전략

1. 성능 최적화: 내부 리소스 DIRECT

// CDN, 정적 리소스는 직접 접속
if (dnsDomainIs(host, "cdn.jsdelivr.net") ||
dnsDomainIs(host, "cdnjs.cloudflare.com")) \{
return "DIRECT";
\}

2. 호환성: 특정 서비스 우회

// Microsoft 365 서비스는 프록시 우회 (인증 문제 방지)
if (dnsDomainIs(host, "office365.com") ||
dnsDomainIs(host, "sharepoint.com") ||
dnsDomainIs(host, "teams.microsoft.com")) \{
return "DIRECT";
\}

3. 보안: 신뢰 도메인만 RBI 우회

// 회사 내부 시스템은 DIRECT
if (dnsDomainIs(host, "intranet.company.com") ||
dnsDomainIs(host, "erp.company.com")) \{
return "DIRECT";
\}

PAC 파일 테스트 방법

// 테스트용 PAC 파일에 디버그 로그 추가
function FindProxyForURL(url, host) \{
var result;

if (dnsDomainIs(host, "shieldgate.softcamp.co.kr")) \{
result = "DIRECT";
\} else if (isInNet(dnsResolve(host), "192.168.0.0", "255.255.0.0")) \{
result = "DIRECT";
\} else \{
result = "PROXY 10.14.10.176:9999";
\}

// 브라우저 콘솔에 로그 출력 (디버깅 시에만 사용)
alert("URL: " + url + "\nHost: " + host + "\nResult: " + result);

return result;
\}

온라인 PAC 테스터 활용:

  • PacParser에서 PAC 파일 업로드 후 테스트

보안 메커니즘

1. TLS MITM (Man-In-The-Middle)

RBIProxy는 HTTPS 트래픽을 검사하기 위해 MITM 기법을 사용합니다.

동작 과정

[사용자 브라우저]

│ CONNECT example.com:443

[RBIProxy]

│ ① HTTP/1.0 200 OK 응답
│ ② example.com용 TLS 인증서 동적 발급
│ ③ 사용자와 TLS 핸드셰이크
│ ④ 암호화된 요청 복호화
│ ⑤ URL 확인: https://example.com/page
│ ⑥ 리다이렉트 응답 생성

[사용자 브라우저]

│ 자동으로 SHIELDGate로 이동

[SHIELDGate]

사설 인증서 설치 필수

HTTPS MITM이 정상 동작하려면 사용자 PC에 RBIProxy의 CA 인증서를 신뢰해야 합니다.

인증서 다운로드:

curl http://10.14.10.176:9999/RestAPI/cert.cer -o rbiproxy_cert.cer

설치 방법:

  1. Windows:

    • rbiproxy_cert.cer 더블클릭
    • "인증서 설치" 클릭
    • "로컬 컴퓨터" 선택
    • "모든 인증서를 다음 저장소에 저장" → 신뢰할 수 있는 루트 인증 기관
    • 설치 완료
  2. GPO 일괄 배포:

    그룹 정책 관리 → 컴퓨터 구성 → Windows 설정 → 보안 설정
    → 공개 키 정책 → 신뢰할 수 있는 루트 인증 기관
    → rbiproxy_cert.cer 추가

2. RBI 연동 방식

RBIProxy는 두 가지 RBI 연동 방식을 지원합니다:

A. SHIELDGate 방식 (현재 운영 중) ⭐

설정:

RBI_LINK_TYPE: SHIELDGate

코드 위치: src/main.go 320번 줄

URL 형식:

https://shieldgate.softcamp.co.kr/gate-proxy?currentTab=true&url=http://example.com

처리 방식:

  • RBIProxy는 단순 URL 변환만 수행
  • 원본 URL을 쿼리 파라미터로 전달
  • 보안 정책은 SHIELDGate에서 처리

특징:

  • 단순하고 직관적한 구조
  • URL이 평문으로 노출
  • RBIProxy는 중계기 역할만 수행
  • 정책 관리를 SHIELDGate에 위임

B. DIRECT (JWT) 방식 (현재 미사용)

설정:

RBI_LINK_TYPE: DIRECT

코드 위치: src/main.go 323~342번 줄

URL 형식:

https://rbi.custom.co.kr/view?url=<JWT_TOKEN>

JWT 토큰 내용 (src/main.go 329~339번 줄에 하드코딩):

\{
"ver": "1.0",
"id": "softcamp.co.kr",
"url": "http://example.com",
"policy": \{
"screenmark": "OFF", // 화면 워터마크
"key": "ON", // 키보드 입력 허용
"site": "ON", // 사이트 접근 허용
"dn": "ON", // 다운로드 허용
"up": "ON", // 업로드 허용
"media": "ON", // 미디어 재생 허용
"menu": "ON", // 메뉴 사용 허용
"clip": "ON" // 클립보드 사용 허용
\},
"exp": 1234567890 // 만료 시간 (12시간 후)
\}

특징:

  • URL이 JWT 토큰으로 암호화
  • 토큰 만료 시간 설정 (12시간)

제약사항:

  • ⚠️ 정책이 코드에 하드코딩되어 있음
  • ⚠️ 모든 요청에 동일한 정책 적용
  • ⚠️ 사용자별/URL별 다른 정책 적용 불가
  • ⚠️ ConfigMap이나 설정 파일로 변경 불가
  • 현재 운영 환경에서는 사용되지 않음

방식 비교 요약

항목SHIELDGate 방식 (운영 중)DIRECT (JWT) 방식 (미사용)
설정값RBI_LINK_TYPE: SHIELDGateRBI_LINK_TYPE: DIRECT
URL 변환쿼리 파라미터로 평문 전달JWT 토큰으로 암호화
정책 처리SHIELDGate에서 처리JWT 토큰에 포함 (하드코딩)
정책 유연성SHIELDGate에서 유연하게 관리불가능 (코드 수정 필요)
RBIProxy 역할단순 중계기URL + 정책 패키징
현재 사용 여부✅ 사용 중❌ 미사용

왜 SHIELDGate 방식을 사용하는가?

현재 운영 환경 분석 (ConfigMap 기준):

# build/kube-deploy.yaml
RBI_LINK_TYPE: SHIELDGate # ← 실제 운영 설정
RBI_BASEURL: https://devshieldgate.softcamp.co.kr

SHIELDGate 방식 선택 이유:

  1. 단순성:
    • RBIProxy는 URL 변환만 수행 (src/main.go 320번 줄)
    • 보안 정책 관리를 SHIELDGate에 완전히 위임
    • 코드 수정 없이 SHIELDGate에서 정책 변경 가능
  2. 유지보수성:
    • JWT 방식의 정책은 src/main.go 329~339번 줄에 하드코딩
    • 정책 변경 시 코드 수정 → 빌드 → 배포 필요
    • SHIELDGate 방식은 SHIELDGate 설정만 변경하면 됨
  3. 운영 유연성:
    • 사용자별/그룹별 다른 정책 적용은 SHIELDGate에서 관리
    • RBIProxy는 모든 사용자에게 동일하게 동작
    • 정책 변경에 RBIProxy 재배포 불필요

결론:

  • RBIProxy는 "똑똑한 URL 변환기" 역할에 집중
  • 복잡한 정책 관리는 SHIELDGate의 몫
  • 단순하고 안정적인 아키텍처

3. 무한 루프 방지

RBIProxy와 SHIELDGate 간의 무한 리다이렉트를 방지하는 메커니즘:

PAC 파일에서 방지:

// SHIELDGate 도메인은 DIRECT로 접속 (프록시 우회)
if (dnsDomainIs(host, "shieldgate.softcamp.co.kr")) \{
return "DIRECT"; // 무한 루프 방지
\}

동작 원리:

사용자가 example.com 입력

PAC: PROXY → RBIProxy로

RBIProxy: shieldgate.softcamp.co.kr/gate-proxy?url=example.com 으로 리다이렉트

사용자 브라우저가 shieldgate.softcamp.co.kr 접속 시도

PAC: "shieldgate.softcamp.co.kr? DIRECT!" ← 여기서 차단!

shieldgate.softcamp.co.kr에 직접 접속 (RBIProxy 안 거침)

무한 루프 방지 ✅

만약 PAC에서 예외 처리하지 않으면:

❌ 무한 루프 발생:
example.com → RBIProxy → shieldgate... → RBIProxy → shieldgate... (반복)

REST API

RBIProxy는 관리 및 모니터링을 위한 REST API를 제공합니다.

1. 버전 및 헬스체크

엔드포인트: GET / 또는 GET /ver

curl http://10.14.10.176:9999/ver

응답:

\{
"code": 0,
"msg": "안녕, Hi, こんにちは, 你好, Chào...",
"ver": "1.0.0.5"
\}

용도:

  • 서비스 동작 확인
  • 버전 정보 조회
  • Kubernetes Liveness/Readiness Probe

2. 활성 세션 모니터링

엔드포인트: GET /sessions

인증:

  • localhost에서 접속 시 인증 불필요
  • 외부 접속 시 Basic Auth 필요
# Basic Auth 사용
curl -u admin:password http://10.14.10.176:9999/sessions

응답:

\{
"code": 0,
"msg": "",
"total": 2,
"sessions": [
\{
"client": "192.168.1.100:48068",
"req": "GET https://example.com",
"time": "295.508µs"
\},
\{
"client": "192.168.1.101:37988",
"req": "CONNECT secure.example.com:443",
"time": "1.381s"
\}
]
\}

용도:

  • 실시간 트래픽 모니터링
  • 성능 분석 (요청 처리 시간)
  • 사용자 접속 추적

3. PAC 파일 배포

엔드포인트: GET /RestAPI/pac.js

curl http://10.14.10.176:9999/RestAPI/pac.js

응답: JavaScript PAC 파일

용도:

  • 사용자 PC의 프록시 자동 설정
  • 중앙에서 PAC 파일 관리

4. 사설 인증서 배포

엔드포인트: GET /RestAPI/cert.cer

curl http://10.14.10.176:9999/RestAPI/cert.cer -o rbiproxy_cert.cer

응답: PEM 형식의 CA 인증서

용도:

  • HTTPS MITM을 위한 사설 인증서 배포
  • 사용자 PC에 설치하여 인증서 경고 제거

기술 스택

언어 및 프레임워크

기술버전용도
Go (Golang)1.23.11메인 언어
Alpine Linux3.21.3Docker 베이스 이미지
elazarl/goproxy-HTTP/HTTPS 프록시 라이브러리

주요 Go 패키지

rbiproxy/
├── cert/ # TLS 인증서 동적 발급 (MITM)
├── config/ # 설정 파일 로드 (config.yaml, 환경변수)
├── restapi/ # REST API 서버
│ └── core/ # API 핸들러 (version, sessions)
└── main.go # 프록시 서버 메인 로직

외부 의존성

  • github.com/elazarl/goproxy: HTTP/HTTPS 프록시 엔진
  • github.com/spf13/viper: 설정 파일 관리
  • dev.azure.com/Security365/go-common:
    • JWT 토큰 생성/검증
    • 로거
    • 유틸리티

빌드 및 배포

Docker 이미지 빌드:

docker build -t rbiproxy:latest -f build/Dockerfile .

버전 관리:

  • build/version.txt: 메이저.마이너.패치 버전
  • build/version-patch.txt: 패치 번호
  • 빌드 시 자동으로 버전 정보 삽입

사용 사례

Case 1: 전사 웹 보안 강화

문제:

  • 직원들이 업무 중 악성 웹사이트 접속
  • 랜섬웨어, 악성코드 다운로드 위험
  • 피싱 사이트 접속으로 인한 계정 탈취

해결:

[모든 직원 PC]
↓ (GPO로 PAC 자동 배포)
[RBIProxy]
↓ (자동 리다이렉트)
[SHIELDGate 격리 브라우저]
↓ (안전한 접속)
[외부 웹사이트]

결과: 악성코드가 격리 환경에서만 실행, 직원 PC는 안전

Case 2: 특정 부서만 RBI 적용

요구사항:

  • 개발팀은 자유로운 인터넷 사용 필요 (DIRECT)
  • 일반 부서는 RBI를 통한 보안 접속

구현:

// 개발팀 IP 대역
function FindProxyForURL(url, host) \{
var clientIP = myIpAddress();

// 개발팀 IP 대역은 DIRECT
if (isInNet(clientIP, "10.14.20.0", "255.255.255.0")) \{
return "DIRECT";
\}

// 그 외 일반 부서는 RBIProxy 사용
if (/* 예외 조건들 */) \{
return "DIRECT";
\}

return "PROXY 10.14.10.176:9999";
\}

Case 3: 고위험 카테고리만 RBI 적용

요구사항:

  • 신뢰할 수 있는 사이트(Microsoft, Google)는 DIRECT
  • 알려지지 않은 사이트만 RBI 적용

구현:

function FindProxyForURL(url, host) \{
// 신뢰 도메인 리스트
var trustedDomains = [
"microsoft.com", "google.com", "github.com",
"stackoverflow.com", "azure.com"
];

for (var i = 0; i < trustedDomains.length; i++) \{
if (dnsDomainIs(host, trustedDomains[i])) \{
return "DIRECT";
\}
\}

// 기타 사이트는 RBIProxy 경유
return "PROXY 10.14.10.176:9999";
\}

Case 4: 모니터링 및 로깅

요구사항:

  • 실시간 트래픽 모니터링
  • 어떤 사용자가 어떤 사이트에 접속하는지 추적

구현:

# 실시간 활성 세션 모니터링
watch -n 2 'curl -s http://10.14.10.176:9999/sessions | jq .'

# 로그 파일 실시간 확인 (Kubernetes)
kubectl logs -f deployment/rbiproxy -n shieldinfo-dev

# 특정 사용자 IP 필터링
kubectl logs deployment/rbiproxy -n shieldinfo-dev | grep "192.168.1.100"

배포 아키텍처

Kubernetes 환경

┌────────────────────────────────────────────────────────────┐
│ Kubernetes Cluster │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Namespace: shieldinfo-dev │ │
│ │ │ │
│ │ ┌──────────────────┐ ┌──────────────────┐ │ │
│ │ │ ConfigMap │───→│ Deployment │ │ │
│ │ │ rbiproxy-config │ │ │ │ │
│ │ │ │ │ ┌────────────┐ │ │ │
│ │ │ RBI_BASEURL │ │ │ rbiproxy │ │ │ │
│ │ │ RBI_LINK_TYPE │ │ │ Container │ │ │ │
│ │ │ RBIPROXY_PORT │ │ │ │ │ │ │
│ │ └──────────────────┘ │ │ Port:9999 │ │ │ │
│ │ │ └────────────┘ │ │ │
│ │ └────────┬─────────┘ │ │
│ │ │ │ │
│ │ ┌────────▼─────────┐ │ │
│ │ │ Service │ │ │
│ │ │ rbiproxy │ │ │
│ │ │ │ │ │
│ │ │ Port 80, 9999 │ │ │
│ │ └────────┬─────────┘ │ │
│ └────────────────────────────────────┼────────────────┘ │
│ │ │
│ ┌─────────────────────────────────────▼────────────────┐ │
│ │ Namespace: kube-system │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────┐ │ │
│ │ │ rke2-ingress-nginx-controller │ │ │
│ │ │ │ │ │
│ │ │ - containerPort.rbiproxy: 9999 │ │ │
│ │ │ - tcp-services ConfigMap 참조 │ │ │
│ │ └───────────────────┬──────────────────────────┘ │ │
│ │ │ │ │
│ │ ┌───────────────────▼──────────────────────────┐ │ │
│ │ │ Service (NodePort/LoadBalancer) │ │ │
│ │ │ Port 9999 외부 노출 │ │ │
│ │ └───────────────────┬──────────────────────────┘ │ │
│ └──────────────────────┼───────────────────────────────┘ │
│ │ │
└─────────────────────────┼─────────────────────────────────────┘

│ NodePort or LoadBalancer

┌───────────────┐
│ 외부 접속 │
│ (사용자 PC) │
└───────────────┘

고가용성 구성

다중 Replica 배포:

spec:
replicas: 3 # 3개 인스턴스 실행
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1 # 최대 1개까지만 동시 다운
maxSurge: 1 # 최대 1개까지 추가 생성

HPA (Horizontal Pod Autoscaler):

# CPU 사용률 기반 자동 스케일링
kubectl autoscale deployment rbiproxy \
--cpu-percent=70 \
--min=2 \
--max=10 \
-n shieldinfo-dev

환경변수

Kubernetes ConfigMap을 통해 설정을 주입합니다.

필수 환경변수

환경변수예시 값설명
RBIPROXY_PORT9999프록시 서비스 포트
RBI_BASEURLhttps://shieldgate.softcamp.co.krSHIELDGate 서버 주소 (끝에 / 자동 추가됨)
RBI_LINK_TYPESHIELDGate연동 방식 (SHIELDGate 또는 DIRECT)
TZAsia/Seoul타임존 (로그 시간 표시용)

선택 환경변수

환경변수기본값설명
LOG_LEVELinfo로그 레벨 (error, warn, info, debug)
RESTAPI_JWT_SECRET_B64자동 생성JWT 서명 시크릿 (Base64)

환경변수 우선순위

1순위: 환경변수 (ConfigMap/환경변수)
2순위: config.yaml 파일
3순위: 커맨드라인 플래그

Kubernetes 배포 시 ConfigMap의 환경변수가 최우선 적용됩니다.


성능 및 리소스

리소스 요구사항

환경CPU RequestCPU LimitMemory RequestMemory LimitReplicas
개발/테스트100m500m200Mi512Mi1
소규모 운영200m700m300Mi1Gi2
중규모 운영500m1000m500Mi2Gi3
대규모 운영1000m2000m1Gi3Gi5+

예상 처리량

단일 인스턴스 기준 (리소스: 700m CPU, 1Gi Memory):

  • 동시 연결: 약 500~1,000개
  • 초당 요청: 약 100~200 req/s
  • 응답 시간: 평균 10~50ms (리다이렉트만)

실제 성능은 다음 요인에 따라 달라집니다:

  • 네트워크 대역폭
  • SHIELDGate 응답 속도
  • TLS 핸드셰이크 오버헤드

병목 지점

  1. TLS MITM: 각 HTTPS 요청마다 핸드셰이크 필요 → CPU 사용량 증가
  2. 동적 인증서 발급: 도메인별 인증서 생성 → 메모리 사용량 증가
  3. 로깅: 모든 요청을 로깅하면 I/O 부하 증가

최적화 팁:

  • 로그 레벨을 warn 또는 error로 낮춤
  • Replica 수 증가로 부하 분산
  • SHIELDGate 서버와 같은 네트워크에 배치 (레이턴시 감소)

로깅 및 모니터링

로그 형식

2026-04-01 15:23:45 [INFO] Local HTTP Request - IP: 192.168.1.100:52341, URL: http://example.com, Method: GET
2026-04-01 15:23:45 [INFO] Local [GET http://example.com] code=200 OK elap=12ms

2026-04-01 15:24:10 [INFO] Local HTTPS CONNECT Request - IP: 192.168.1.100:52342, Host: secure.example.com:443
2026-04-01 15:24:10 [INFO] Local HTTPS Detail - IP: 192.168.1.100:52342, Method: GET, URL: https://secure.example.com/
2026-04-01 15:24:10 [INFO] Local [CONNECT secure.example.com:443] GET https://secure.example.com/ code=200 OK elap=45ms

로그 분류

로그 타입설명의미
Local HTTP Request일반 브라우저의 HTTP 요청 수신사용자가 HTTP 사이트 접속 시도
Local HTTPS CONNECT일반 브라우저의 HTTPS CONNECT 요청사용자가 HTTPS 사이트 접속 시도
Local HTTPS DetailHTTPS 요청의 실제 내용TLS 복호화 후 확인된 URL

Prometheus 메트릭 (향후 추가 가능)

# 활성 세션 수
rbiproxy_active_sessions_total

# 요청 처리 시간 (히스토그램)
rbiproxy_request_duration_seconds

# 요청 수
rbiproxy_requests_total

# 에러 발생 수
rbiproxy_errors_total\{type="tls|redirect|connection"\}

보안 고려사항

1. 사설 인증서 관리

위험:

  • RBIProxy의 CA 인증서가 유출되면 MITM 공격 가능
  • 인증서 유효기간 만료 시 서비스 중단

대응:

  • CA 인증서 파일(proxy_cert.pem, proxy_pkey.pem)을 안전하게 보관
  • Kubernetes Secret으로 관리 (ConfigMap 대신)
  • 주기적인 인증서 갱신 (예: 1년마다)

인증서 재생성:

openssl req -x509 -newkey rsa:4096 \
-keyout proxy_pkey.pem \
-out proxy_cert.pem \
-sha256 -days 3650 -nodes \
-subj "/C=KR/ST=Seoul/O=Security365/CN=RBIProxy" \
-addext "subjectAltName=DNS:RBIProxy"

2. REST API 접근 제어

위험:

  • /sessions API로 사용자 트래픽 노출 가능

대응:

  • Basic Auth 설정 필수
  • localhost 외부 접속 시 인증 강제
  • Kubernetes NetworkPolicy로 API 접근 제한

Basic Auth 설정 (config.yaml):

restapi:
basicAuth:
username: admin
password: strong_password_here

3. 무한 루프 방지

위험:

  • PAC 파일에서 SHIELDGate를 DIRECT로 처리하지 않으면 무한 루프 발생

대응:

// PAC 파일에 반드시 포함
if (dnsDomainIs(host, "shieldgate.softcamp.co.kr")) \{
return "DIRECT"; // 프록시 우회
\}

4. 내부 네트워크 격리

권장 구성:

DMZ:        [RBIProxy] ← 사용자 PC 접근
Internal: [SHIELDGate] ← RBIProxy만 접근 가능

NetworkPolicy 예시:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: rbiproxy-policy
spec:
podSelector:
matchLabels:
app: rbiproxy
ingress:
- from:
- namespaceSelector:
matchLabels:
name: dmz
ports:
- protocol: TCP
port: 9999

고급 설정

1. 다중 RBI 서버 지원

시나리오: 부서별로 다른 RBI 서버 사용

구현 방법:

  • RBIProxy를 여러 개 배포 (각각 다른 RBI_BASEURL 설정)
  • PAC 파일에서 IP 대역별로 다른 프록시 지정
function FindProxyForURL(url, host) \{
var clientIP = myIpAddress();

// 개발팀 (10.14.20.0/24) → RBIProxy-Dev
if (isInNet(clientIP, "10.14.20.0", "255.255.255.0")) \{
return "PROXY 10.14.10.100:9999";
\}

// 일반 부서 → RBIProxy-Prod
return "PROXY 10.14.10.176:9999";
\}

2. 화이트리스트 중앙 관리

현재: PAC 파일에 예외 도메인을 하드코딩

개선 방안:

  • 중앙 관리 시스템(DB, Redis 등)에서 예외 도메인 목록 관리
  • RBIProxy가 동적으로 로드
  • PAC 파일을 템플릿으로 생성

3. 지역별 RBI 서버 분산

시나리오: 지사별로 가까운 RBI 서버 사용

function FindProxyForURL(url, host) \{
var clientIP = myIpAddress();

// 서울 본사 (10.14.0.0/16)
if (isInNet(clientIP, "10.14.0.0", "255.255.0.0")) \{
return "PROXY 10.14.10.176:9999"; // 서울 RBIProxy
\}

// 부산 지사 (10.20.0.0/16)
if (isInNet(clientIP, "10.20.0.0", "255.255.0.0")) \{
return "PROXY 10.20.10.50:9999"; // 부산 RBIProxy
\}

return "DIRECT";
\}

FAQ (자주 묻는 질문)

Q1: RBIProxy가 다운되면 인터넷이 안되나요?

A: 예. 프록시가 다운되면 모든 웹 접속이 불가능합니다.

대응 방안:

  • 고가용성 구성: 다중 Replica 배포 (최소 2개)

  • Failover: PAC 파일에 백업 프록시 지정

    // 메인 프록시 실패 시 백업 프록시 사용
    return "PROXY 10.14.10.176:9999; PROXY 10.14.10.177:9999; DIRECT";
  • 모니터링: Prometheus + Grafana로 실시간 상태 확인

  • 알람: Alertmanager로 다운 시 즉시 알림

Q2: 특정 사용자만 RBI를 적용할 수 있나요?

A: 예. PAC 파일에서 IP 대역 또는 사용자별 분기가 가능합니다.

function FindProxyForURL(url, host) \{
var clientIP = myIpAddress();

// VIP/임원진은 DIRECT 접속 허용
if (isInNet(clientIP, "10.14.1.0", "255.255.255.0")) \{
return "DIRECT";
\}

// 일반 직원은 RBIProxy 경유
return "PROXY 10.14.10.176:9999";
\}

Q6: 로그에서 어떤 정보를 확인할 수 있나요?

A: 다음 정보를 로깅합니다:

  • 클라이언트 IP 주소
  • 요청 URL 및 Method
  • 응답 시간
  • HTTP 상태 코드

개인정보 보호:

  • POST 바디는 로깅하지 않음
  • 쿠키, Authorization 헤더는 로깅하지 않음
  • URL의 쿼리 파라미터는 로깅됨 (민감 정보 포함 가능)

제한사항 및 알려진 이슈

1. WebSocket 지원 제한

현상: WebSocket 연결이 정상 동작하지 않을 수 있음

원인: HTTP Upgrade 요청 처리 미지원

해결: WebSocket을 사용하는 사이트는 PAC 예외 처리

// WebSocket 사용 사이트 예외
if (dnsDomainIs(host, "slack.com") ||
dnsDomainIs(host, "teams.microsoft.com")) \{
return "DIRECT";
\}

2. 일부 인증 방식 호환성 문제

현상: 클라이언트 인증서 기반 사이트 접속 불가

원인: MITM 과정에서 클라이언트 인증서가 전달되지 않음

해결: 해당 사이트를 PAC 예외 처리

3. HTTP/2 및 HTTP/3

현재 상태: HTTP/1.1만 완전 지원

HTTP/2: goproxy 라이브러리 제약으로 제한적 지원

HTTP/3: 미지원 (QUIC 프로토콜)


관련 문서

설치 및 운영

  • [구축 가이드](../../내부 문서/구축-설치-운영 가이드/RBI Proxy/RBIProxy 구축 가이드.md): Kubernetes 배포 전체 절차
  • [환경변수](../../내부 문서/구축-설치-운영 가이드/RBI Proxy/RBIProxy config.js 가이드.md): ConfigMap 설정 상세
  • main.go 코드 분석: 내부 동작 원리

REST API

프로젝트 정보

  • README.md: 프로젝트 개요 및 변경 이력

라이선스 및 오픈소스

사용 중인 오픈소스

라이브러리라이선스용도
elazarl/goproxyBSD-3-ClauseHTTP/HTTPS 프록시 엔진
spf13/viperMIT설정 파일 관리

변경 이력

RBIProxy는 원래 lqqyt2423/go-mitmproxy를 기반으로 했으나, elazarl/goproxy로 변경되었습니다 (v1.0.0.1, 2024-06-11).

변경 이유:

  • 더 나은 HTTPS 처리
  • 안정적인 MITM 기능
  • 활발한 커뮤니티 지원

요약

RBIProxy는:

  • 사용자 PC와 인터넷 사이의 투명한 보안 계층
  • Windows PAC를 통해 자동으로 적용되는 프록시
  • SOFTCAMP SHIELDGate와 연동하여 웹 접속을 격리 환경으로 전환
  • PAC 파일을 통한 선별적 필터링으로 무한 루프 방지
  • Kubernetes에서 손쉽게 배포 및 확장 가능

한 줄 요약:
"PAC 필터링을 통과한 트래픽을 SHIELDGate로 변환하는 URL 변환 프록시"


다음 단계

  1. [구축 가이드](../../내부 문서/구축-설치-운영 가이드/RBI Proxy/RBIProxy 구축 가이드.md)를 참고하여 배포
  2. PAC 파일을 환경에 맞게 커스터마이징
  3. 사용자 PC에 CA 인증서 설치
  4. Windows GPO로 PAC 설정 일괄 배포
  5. 모니터링 대시보드 구축 (/sessions API 활용)

문의:

  • 기술 지원: SOFTCAMP
  • 프로젝트 관리: nicejh

최종 수정: 2026-04-01